﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using Microsoft.Xna.Framework;

using FXnaEngine.Components;




namespace FXnaEngine
{
   public class FEntity
    {



       public FEntity(FGame game)
       {

           this.game = game;

           this.game.GameMessage += new EngineMessageHandler(game_GameMessage);


           this.guid = Guid.NewGuid();


           //初始化

           this.componentList = new Dictionary<Type, FComponent>();
         





           //为每一个entity都提供变换类

           FTransformComponent tran = new FTransformComponent(this);
           this.AddComponent(tran);






       }

       void game_GameMessage(IMessage message)
       {

           // For messages handled directly by the Entity but aren't Request Protocol,
           // we still pass them to the Entity's components in case those components care.            
           if (message.Protocol != MessageProtocol.Request)
           {
               SendMessageThroughComponents(message);
           }

           

          
       }

       /// <summary>
       /// Sends a message through each component until it is handled. If the message does not
       /// have a request protocol then the message continues sending to all components.
       /// </summary>
       /// <param name="message">Message to distribute</param>
       private bool SendMessageThroughComponents(IMessage message)
       {
           bool handled = false;

           foreach (KeyValuePair<Type, FComponent> pair in this.componentList)
           {
               // If message is handled, quit sending message through components
               if ((pair.Value).ExecuteMessage(message))
               {
                   handled = true;

                   if (message.Protocol == MessageProtocol.Request)
                   {
                       break;
                   }
               }
           }

           return handled;
       }





       Guid guid;

       public Guid Guid
       {
           get { return guid; }
          
       }


       FGame game;

       public FGame Game
       {
           get { return game; }
          
       }


       /// <summary>
       /// Reference to this entity's parent entity (if it has one).
       /// </summary>
       public Entity ParentEntity
       {
           get { return this.parentEntity; }
       }
       private Entity parentEntity;


       public bool HasParent
       {
           get { return (this.parentEntity != null); }
       }


      


        /// <summary>
        /// List of all the components attached to this entity.
        /// </summary>
        private Dictionary<Type, FComponent> componentList;





        #region 对外属性

        public FTransformComponent Transform
        {
            get {

               return this.GetComponentByType(typeof(FTransformComponent)) as FTransformComponent;

            }
        }


        public BoundingSphere BoundingSphere
        {

            get {

                BoundingSphere b = new BoundingSphere();
                

                return b;



            }
 

        }


        #endregion


        /// <summary>
        /// Entity update methods
        /// </summary>
        /// <param name="gameTime">Contains timer information</param>
        public void Update(GameTime gameTime)
        {
            //暂时不启用components的设置，以后查看启用的原因，目前不明


            //for (int i = this.activeComponents.Count - 1; i >= 0; --i)
            //{
            //    this.activeComponents[i].Update(gameTime);
            //}

            foreach (FComponent item in this.componentList.Values)
            {
                item.Update(gameTime);
                
            }


        }



        public FRendererComponent GetRendererComponent()
        {

            foreach (FComponent item in this.componentList.Values)
            {

                if (item is FRendererComponent)
                {
                    return item as FRendererComponent;
                    
                }
                
            }

            return null;

            
        }



        public FComponent GetComponentByType(Type type)
        {
            FComponent returnVal = null;
            this.componentList.TryGetValue(type, out returnVal);

            return returnVal;
        }




        /// <summary>
        /// Attaches a component to this entity.
        /// </summary>
        /// <param name="component">Component to attach</param>
        public void AddComponent(FComponent component)
        {
            FComponent dummy = null;

            //确定之前没有对应的component类型

            if (!this.componentList.TryGetValue(component.GetType(), out dummy))
            {
                this.componentList.Add(component.GetType(), component);
            }
        }


        /// <summary>
        /// Removes a component from this entity.
        /// </summary>
        /// <param name="component">Component to remove</param>
        public void RemoveComponent(FComponent component)
        {
            FComponent dummy = null;
            if (this.componentList.TryGetValue(typeof(FComponent), out dummy))
            {
                component.Shutdown();

                this.componentList.Remove(typeof(FComponent));
               
            }
        }


       /// <summary>
       /// 退出前的清空逻辑
       /// </summary>
        public void Shutdown()
        { 

        }




    }
}
